package com.wms.service.impl;

import com.wms.entity.Resource;
import com.wms.entity.enums.ResourceTypeEnum;
import com.wms.mapper.ResourceMapper;
import com.wms.service.ResourceService;
import com.wms.service.RoleResourceService;
import io.jsonwebtoken.lang.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
public class ResourceServiceImpl extends BaseServiceImpl<ResourceMapper, Resource> implements ResourceService {

    @javax.annotation.Resource
    private ResourceMapper resourceMapper;

    @Autowired
    private RoleResourceService roleResourceService;



    @Override
    @Transactional
    public void deleteById(Long id) {
        Assert.notNull(id);

        Resource resource = findById(id);

        if (resource != null){
            List<Long> ids = getIds(new ArrayList<Long>(), resource);
            removeByIds(ids);

            resourceMapper.delRole(ids);
            resourceMapper.delAuthority(ids);
        }
    }

    @Override
    public Resource findById(Long id) {
        if (id == null) return null;
        return resourceMapper.findById(id);
    }

    @Override
    public List<Resource> findTree(Long roleId) {
        List<Resource> resourceList = resourceMapper.findTree();
        if (roleId != null){
            List<Long> resourceIds = roleResourceService.findResourceIdsByRoleId(roleId);
            if (resourceIds != null && !resourceIds.isEmpty()){
                for (Resource resource : resourceList){
                    setChecked(resource, resourceIds);
                }
            }
        }
        return resourceList;
    }

    @Override
    public List<Resource> getMenuByUsername(String username) {
        Assert.notNull(username);
        List<Resource> resources = resourceMapper.getMenuByUsername(username);
        return buildTree(resources);
    }


    private List<Resource> buildTree(List<Resource> list){
        if (list == null || list.isEmpty()) return new ArrayList<Resource>();
        List<Resource> tree = new ArrayList<Resource>();

        Iterator<Resource> iterator = list.iterator();
        while (iterator.hasNext()){
            Resource resource = iterator.next();
            if (resource.getType() == ResourceTypeEnum.MENU){
                iterator.remove();
                tree.add(resource);
                setChildren(resource, list);
            }
        }
        return tree;
    }

    private void setChildren(Resource target, List<Resource> list){
        List<Resource> children = new ArrayList<Resource>();
        for (Resource resource : list) {
            if (resource.getParentId().equals(target.getId())) {
                children.add(resource);
                setChildren(resource, list);
            }
        }
        target.setChildren(children);
    }


    private void setChecked(Resource resource, List<Long> resourceIds){
        for (Long id : resourceIds) {
            if (id.equals(resource.getId())){
                resource.setChecked(true);
                break;
            }
        }

        if (resource.getChildren() != null && !resource.getChildren().isEmpty()){
            for (Resource item:resource.getChildren()){
                setChecked(item, resourceIds);
            }
        }
    }

    public List<Long> getIds(List<Long> ids, Resource resource){
        ids.add(resource.getId());
        if (resource.getChildren() != null && !resource.getChildren().isEmpty()){
            for (Resource r:resource.getChildren()){
                getIds(ids, r);
            }
        }
        return ids;
    }


}
